package com.dora.basic.juc.blockqueue;

/**
 * 手动阻塞队列
 * 
 */
public class MyBlockingQueue {

    //锁对象
    private Object object = new Object();

    //队列采用循环队列  数组
    private String[] data = new String[1000];

    //头指针 加volatile防止内存可见性问题
    private volatile int head = 0;
    //尾指针
    private volatile int tail = 0;
    //有效长度
    private volatile int size = 0;

    //带有阻塞性质的入队操作put
    public void put(String str) throws InterruptedException {
        synchronized (object) {
            //队列满时
            while (size == data.length) {
                //阻塞等待 等待另一个线程调用notify方法唤醒
                object.wait();
            }
            //队列不满 入队列
            data[tail] = str;
            tail++;
            size++;
            object.notify();

            //由于数组循环使用 也防止索引出界
            if (tail == data.length) {
                tail = 0;
            }
        }
    }

    //带有阻塞性质的出队列操作
    public String take() throws InterruptedException {
        synchronized (object) {
            //队列为空
            while (size == 0) {
                //阻塞等待
                object.wait();
            }
            //队列不为空
            String tmp = data[head];
            head++;
            if (head == data.length) {
                head = 0;
            }
            size--;
            //唤醒
            object.notify();
            return tmp;
        }
    }
}